<?php

namespace App\Models\video;

use App\Http\Config\ErrorCode;
use App\Library\UpTools;
use Illuminate\Support\Str;

// 云点播处理
class VodHandle
{
    protected $returnData;
    static $object;
    protected $reviewType = [
        "Porn" => "鉴黄",
        "Porn.Asr" => "鉴黄",
        "Porn.Ocr" => "鉴黄",
        "Political" => "鉴政",
        "Political.Asr" => "鉴政",
        "Political.Ocr" => "鉴政",
        "Terrorism" => "鉴恐",
        "Terrorism.Ocr" => "鉴恐",
        "Prohibited.Asr" => "违禁",
        "Prohibited.Ocr" => "违禁",
    ];

    public function __construct()
    {
        $this->returnData = ErrorCode::$admin_enum["success"];
    }

    /**
     * @return VodHandle
     */
    public static function getInstance(){
        if(empty(self::$object)){
            self::$object = new self();
        }
        return self::$object;
    }

    public function getUrlBySign($url, $videoDuration = 0, $exper = 0, $rlimit = 0){
        static $settingData;
        if(empty($settingData)) {
            $settingData = VideoSettingModel::getFields("vod_key", ["mall_id" => request()->mallData["id"]], true, false);
        }
        if(!$settingData["vodKey"]){
            return $url;
        }
        $urlInfo = parse_url($url);
        $t = dechex(time() + $videoDuration); // 播放地址的过期时间戳的十六进制
        $us = Str::random(10); // 随机字符串
        $string = $settingData["vodKey"].dirname($urlInfo["path"])."/".$t;
        $url = $url."?t={$t}";
        if($exper){ // 试看秒数
            $exper = $exper + 2;
            $string .= $exper;
            $url .= "&exper={$exper}";
        }
        if($rlimit){ // IP数量限制
            $string .= $rlimit;
            $url .= "&rlimit={$rlimit}";
        }
        $sign = md5($string.$us);
        $url .= "&us={$us}&sign={$sign}";
        return $url;
    }

    public function getTryTime($videoDuration){ // 单位：秒
        if($videoDuration <= 100){
            $time = floor($videoDuration / 10);
            $time = $time ?: 1;
        }elseif($videoDuration <= 600){ // 10分钟内
            $time = round($videoDuration / 100);
            $time = ($time - 1) * 20 + 30;
        }elseif($videoDuration <= 1800){ // 半小时内
            $time = round($videoDuration / 300);
            $time = ($time - 2) * 25 + 90;
        }else{
            $time = round($videoDuration / 300);
            $time = ($time - 6) * 20 + 120;
            $time = $time > 300 ? 300 : $time;
        }
        return $time;
    }

    public function sendWxTemplate($data, $mallId, $broadcasterId){
        $userSubscribe = SubscriptionModel::query()->from(SubscriptionModel::query()->getModel()->getTable()." as s")
            ->leftJoin(VideoUserModel::query()->getModel()->getTable()." as u", "u.id", "=", "s.user_id")
            ->select("u.openid", "s.create_time")
            ->where(["s.broadcaster_id" => $broadcasterId, "s.remind_status" => 1])
            ->get()->toArray(); // 查询授权接受订阅消息提醒的用户
        if(!empty($userSubscribe)){
            $templateData = [
                "thing1" => ["value" => "UP主发布新视频动态了"],
                'thing4' => ["value" => "视频名称：{$data["title"]}，简介：{$data['desc']}；"],
                "thing2" => ["value" => "赶紧去围观吧！"]
            ];
            $template_id = SubscribeLibraryModel::query()
                ->where("type", SubscribeLibraryModel::DYNAMIC_REMIND)
                ->where("mall_id", $mallId)
                ->value("template_id");
            foreach ($userSubscribe as $item){
                $templateData['time5'] = ["value" => date("Y年m月d日 H:i", $item['create_time'])];
                WxServer::getInstance()->sendTplNotice($item["openid"], $template_id, $templateData);
            }
        }
    }

    public function handleData($params){
        if(empty($params['EventType'])){
            return $this->returnData;
        }
        switch ($params['EventType']){
            case "FileDeleted": // 文件删除
                $this->handleFileDeleted($params["FileDeleteEvent"]);
                break;
            case "ProcedureStateChanged": // 任务流状态变更
                $this->handleProcedureStateChanged($params["ProcedureStateChangeEvent"]);
                break;
            case "NewFileUpload": // 视频上传完成
                $this->handleFileUpload($params["FileUploadEvent"]);
                break;
            case "PullComplete": // URL 拉取视频
                $this->handlePullComplete($params["PullCompleteEvent"]);
                break;
            case "EditMediaComplete": // 视频编辑完成
                $this->handleEditMediaComplete($params["EditMediaCompleteEvent"]);
                break;
            case "TranscodeComplete": // 视频转码完成
                $this->handleTranscodeComplete($params["TranscodeCompleteEvent"]);
                break;
            case "SnapshotByTimeOffsetComplete": // 指定时间点截图完成
                $this->handleSnapshotByTimeOffsetComplete($params["SnapshotByTimeOffsetCompleteEvent"]);
                break;
            case "ClipComplete": // 视频剪辑完成
                $this->handleClipComplete($params["ClipCompleteEvent"]);
                break;
            case "ComposeMediaComplete": // 视频合成完成 $params["ComposeMediaCompleteEvent"]
            case "WechatPublishComplete": // 微信发布完成 $params["WechatPublishCompleteEvent"]
            case "ConcatComplete": // 视频拼接完成 $params["ConcatCompleteEvent"]
            case "CreateImageSpriteComplete": // 视频截取雪碧图完成 $params["CreateImageSpriteCompleteEvent"]
            case "WechatMiniProgramPublishEvent":
                UpTools::writeLog("未对接{$params['EventType']}：".var_export($params, true), "noComplete.txt");
                break;
        }
        return $this->returnData;
    }

    // 视频上传完成
    public function handleFileUpload($event){
        if(!empty($event["FileId"]) && !empty($event["MetaData"])){
            $videoLength = $this->convertVideoLength($event["MetaData"]["VideoDuration"]);
            $videoData = VodVideoModel::getFields("id,mall_id,file_type", ["vid" => $event["FileId"]], true, false);
            if(!empty($videoData)){
                request()->mallData = ['id' => $videoData["mallId"]];
                VodVideoModel::doUpdate([
                    "media_url" => $event["MediaBasicInfo"]["MediaUrl"], "video_length" => $videoLength, "video_duration" => $event["MetaData"]["VideoDuration"]
                ], ["id" => $videoData["id"]]);
                if(strpos($videoData["fileType"], "audio") === false) { // 视频
                    $resolution = $event["MetaData"]["Height"] > $event["MetaData"]["Width"] ? $event["MetaData"]["Width"] : $event["MetaData"]["Height"];
                    VodApis::getInstance()->handleMediaFile($event["FileId"], $resolution); // 视频处理任务
                }else{ // 音频
                    VodApis::getInstance()->handleMediaFileByAudio($event["FileId"]); // 音频处理任务
                }
            }
        }
    }

    public function convertVideoLength($length, $add = true){ // $length 单位：秒
        if(!$length){
            return "00";
        }
        if($length >= 3600){ // 达到小时了
            $hour = intval($length / 3600);
            $minutes = $this->convertVideoLength($length - ($hour * 3600));
            return ($hour < 10 ? "0{$hour}:" : "{$hour}:").$minutes;
        }elseif($length >= 60){ // 达到分钟了
            $minutes = intval($length / 60);
            $seconds = $this->convertVideoLength($length - ($minutes * 60), false);
            return ($minutes < 10 ? "0{$minutes}:" : "{$minutes}:").$seconds;
        }else{
            $length = intval($length);
            return ($add ? "00:" : "") . ($length < 10 ? "0{$length}" : $length);
        }
    }

    // URL 拉取视频
    public function handlePullComplete($event){
        UpTools::writeLog("：".var_export($event, true), "handlePullComplete.txt");
    }

    // 文件删除
    public function handleFileDeleted($event){
        foreach ($event["FileIdSet"] as $vid){
            VodVideoModel::delByFilter(["vid" => $vid]);
        }
    }

    // 任务流状态变更
    public function handleProcedureStateChanged($event){
        if($event["Status"] == "FINISH" && $event["ErrCode"] == '0'){
            $data = VodVideoModel::getFields("id,cover_img_id,broadcaster_id,mall_id,title,desc,type", ["vid" => $event["FileId"]], true, false);
            if(!empty($data)){
                $adaptiveDynamic = [];
                $videoData = ["video_url_list" => [], "review_content" => ''];
                if($event["AiAnalysisResultSet"]){

                }
                if($event["AiRecognitionResultSet"]){

                }
                if($event["AiContentReviewResultSet"]){ // 审核内容结果
                    foreach ($event["AiContentReviewResultSet"] as $item){
                        $key = str_replace(".", "", $item["Type"])."Task";
                        if($item[$key]["Output"]["Confidence"] != '0' || $item[$key]["Output"]["Suggestion"] != 'pass'){
                            if(isset($this->reviewType[$item["Type"]])){
                                $videoData["review_content"] .= $this->reviewType[$item["Type"]]." ";
                            }
                        }
                    }
                }
                if($event["MediaProcessResultSet"]){ // 视频处理结果
                    foreach ($event["MediaProcessResultSet"] as $item){
                        if($item["Type"] == 'Transcode'){ // 转码列表
                            if($item["TranscodeTask"]["ErrCode"] == '0' && $item["TranscodeTask"]["Status"] == 'SUCCESS') {
                                $resolution = $item["TranscodeTask"]['Output']['Width'] > $item["TranscodeTask"]['Output']['Height'] ? $item["TranscodeTask"]['Output']['Height'] : $item["TranscodeTask"]['Output']['Width'];
                                $videoData["video_url_list"][] = [
                                    'resolution' => "{$resolution}P", "url" => $item["TranscodeTask"]['Output']['Url'],
                                    "Definition" => $item["TranscodeTask"]['Output']['Definition']
                                ];
                            }
                        }elseif($item["Type"] == 'CoverBySnapshot'){ // 封面
                            if($item["CoverBySnapshotTask"]["ErrCode"] == '0' && $item["CoverBySnapshotTask"]["Status"] == 'SUCCESS' && empty($data["coverImgId"])) {
                                $videoData["cover_img_id"] = $item["CoverBySnapshotTask"]['Output']['CoverUrl'];
                            }
                        }elseif($item["Type"] == 'AdaptiveDynamicStreaming'){ // 自适应码流
                            if($item["AdaptiveDynamicStreamingTask"]["ErrCode"] == '0' && $item["AdaptiveDynamicStreamingTask"]["Status"] == 'SUCCESS'){
                                $adaptiveDynamic[] = [
                                    'resolution' => "自适应", "url" => $item["AdaptiveDynamicStreamingTask"]['Output']['Url'],
                                    "Definition" => $item["AdaptiveDynamicStreamingTask"]['Output']['Definition']
                                ];
                            }
                        }else{
                            UpTools::writeLog("未对接handleProcedureStateChanged - MediaProcessResultSet :{$item["Type"]}：".var_export($item, true), "MediaProcess.txt");
                        }
                    }
                }
                if(!empty($videoData["video_url_list"])) {
                    $videoData["video_url_list"] = array_merge(array_reverse($videoData["video_url_list"]), $adaptiveDynamic);
                }else{
                    $videoData["video_url_list"][] = ['resolution' => "默认", "url" => $event["FileUrl"], "Definition" => ""];
                }
                $videoData["video_url_list"] = json_encode($videoData["video_url_list"], JSON_UNESCAPED_UNICODE);
                $videoData["handle_result"] = 2;
                VodVideoModel::doUpdate($videoData, ["id" => $data["id"]]);
                DynamicModel::doUpdate(["status" => 1], ["belong_id" => $data["id"], "type" => 2]);
                DataCacheModel::del("uploadMedia_{$event["FileId"]}");
                $this->sendWxTemplate($data, $data["mallId"], $data["broadcasterId"]);
                if($data["type"] == '2'){ // 课程， 要把课程目录改成生效
                    CourseCatalogModel::doUpdate(["status" => "1"], ["video_id" => $data["id"]]);
                }
            }
        }else{
            UpTools::writeLog(var_export($event, true), "handleProcedureStateChangedfail.txt");
        }
    }

    // 视频编辑完成
    public function handleEditMediaComplete($event){
        UpTools::writeLog("：".var_export($event, true), "handleEditMediaComplete.txt");
    }

    // 视频转码完成
    public function handleTranscodeComplete($event){
        UpTools::writeLog("：".var_export($event, true), "handleTranscodeComplete.txt");
        $data = VodVideoModel::getFields("id", ["vid" => $event["FileId"]], true, false);
        if(!empty($data)){
            $videoData["video_url_list"] = [];
            foreach ($event["PlayInfoSet"] as $item){
                $resolution = $item['Width'] > $item['Height'] ? $item['Height'] : $item['Width'];
                $videoData["video_url_list"][] = [
                    'resolution' => "{$resolution}P", "url" => $item['Url'],
                    "Definition" => $item['Definition']
                ];
            }
            $videoData["video_url_list"] = json_encode($videoData["video_url_list"], JSON_UNESCAPED_UNICODE);
            VodVideoModel::doUpdate($videoData, ["id" => $data["id"]]);
        }
    }

    // 指定时间点截图完成
    public function handleSnapshotByTimeOffsetComplete($event){
        UpTools::writeLog("：".var_export($event, true), "handleSnapshotByTimeOffsetComplete.txt");
    }

    // 视频剪辑完成
    public function handleClipComplete($event){
        UpTools::writeLog("：".var_export($event, true), "handleClipComplete.txt");
    }
}
